/**
 * Created by zhulifeng on 2023/7/28.
 * */
#ifndef MIDDLEWARE_AUTODETECTETHERNETREADER_H
#define MIDDLEWARE_AUTODETECTETHERNETREADER_H

#include <DeviceReader.h>
#include <EthernetReader.h>
#include "Application.h"
#include <poll.h>
#include "Wrapper.h"
#include "Function.h"

class TCPServer;

class UDPServer;

/**
 * 采用主题进行匹配，支持多对多数据收发，以ethernetReader为基础
 */
class AutoDetectEthernetReader : public DeviceReader {
public:
    AutoDetectEthernetReader(TransportProtocol protocol, std::string ifName, std::string dataStruct, uint16_t port);

    ~AutoDetectEthernetReader();

    int64_t onRead(char *buffer, int64_t len) override;
     
    /**
     * 返回socket描述符，一般在 setPostSetupAction() 中使用
     * 
     * @return SOCKET, 无效时返回INVALID_SOCKET
     */
    SOCKET getSocket();
   
    SOCKET getLastClientSocket();

    void setupConnection() override;

    /**
     * 设置 setupConnection() 完成后动作
     * 
     * 传入的函数应同时在 AppDelegate::onConfigure() 中使用 REGISTER_FUNCTIONS() 进行注册
     */
    FLOW_API void setPostSetupAction(void (*func)(AutoDetectEthernetReader *));

    void stop() override;

    FLOW_API int joinMulticastGroup(const std::string addr, const std::string intf = "");

    int leaveMulticastGroup(const std::string addr, const std::string intf = "");

    bool (*checkBuffer)(char *buffer, int64_t dataLen, int64_t bufferLen) = nullptr;

private:
    TransportProtocol protocol;
    char protocolStr[24];
    std::string ifName;
    std::string dataStruct;
    int port;
    std::string multiCastAddress;
    std::string multiCastInterface;
    TCPServer *tcpServer = 0;
    struct pollfd fds[10];
    UDPServer *udpServer = 0;
    SOCKET lastClientSocket = INVALID_SOCKET;
    std::vector<std::pair<std::string, std::string>> mcGroups;
    Function postSetupAction;
};


#endif //MIDDLEWARE_AUTODETECTETHERNETREADER_H
